import cv2
import numpy as np
import pyautogui
from ultralytics import YOLO
import win32gui
import 检测框模块


def get_image_center(image_path, screenshot):
    """
    获取目标图片在截图中的中心坐标
    :param image_path: 目标图片路径
    :param screenshot: 窗口截图
    :return: 目标图片中心坐标 (x, y)，若未找到则返回 None
    """
    template = cv2.imread(image_path, 0)
    screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
    result = cv2.matchTemplate(screenshot_gray, template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= 0.70:  # 匹配阈值
        h, w = template.shape
        center_x = max_loc[0] + w // 2
        center_y = max_loc[1] + h // 2
        return center_x, center_y
    return None


def movefb(hwnd, left, top, window_width, window_height, model, target_center, offset_x=0, offset_y=0,
           click_type='left'):
    """
    根据目标中心坐标移动鼠标并点击
    :param hwnd: 窗口句柄
    :param left: 窗口左边界坐标
    :param top: 窗口上边界坐标
    :param window_width: 窗口宽度
    :param window_height: 窗口高度
    :param model: YOLO 模型
    :param target_center: 目标中心坐标 (x, y)
    :param offset_x: x 方向偏移量
    :param offset_y: y 方向偏移量
    :param click_type: 点击类型
    """
    target_center_x, target_center_y = target_center
    # 模拟飞镖检测（这里假设飞镖是类别 0）
    while True:
        screenshot = 检测框模块.get_window_screenshot(hwnd)
        results = model(screenshot)
        dart_center_x, dart_center_y = None, None
        for result in results:
            boxes = result.boxes.cpu().numpy()
            for box in boxes:
                if int(box.cls[0]) == 0:
                    x1, y1, x2, y2 = box.xyxy[0].astype(int)
                    dart_center_x = int((x1 + x2) / 2) - 10
                    dart_center_y = int((y1 + y2) / 2) - 10
                    break
        if dart_center_x is not None and dart_center_y is not None:
            dx = target_center_x - dart_center_x
            dy = target_center_y - dart_center_y
            distance = np.sqrt(dx ** 2 + dy ** 2)
            if distance <= 3:
                break
            current_x, current_y = pyautogui.position()
            if distance < 15:
                # 当相差小于 15 像素时，固定移动 3 像素
                if dx != 0:
                    dx = 3 if dx > 0 else -3
                if dy != 0:
                    dy = 3 if dy > 0 else -3
            new_x = current_x + dx
            new_y = current_y + dy
            # 限制鼠标在窗口内移动，放宽到 50 个像素
            new_x = max(left - 50, min(new_x, left + window_width + 50))
            new_y = max(top - 50, min(new_y, top + window_height + 50))
            dx = new_x - current_x
            dy = new_y - current_y
            pyautogui.moveRel(dx, dy)
    pyautogui.click(button=click_type)


def click_target_image(image_path, offset_x=-50, offset_y=-50, click_type='left'):
    # 禁用 pyautogui 的安全保护机制
    pyautogui.FAILSAFE = False
    # 加载 YOLOv8n 模型并指定使用 GPU
    model = YOLO(r"h:\yol\yolo\v11\runs\detect\train58\weights\best.pt").to('cuda')
    hwnd = 检测框模块.find_window()
    if hwnd is None:
        print("未找到标题中包含'梦幻西游'的窗口")
        return
    left, top, right, bottom = win32gui.GetWindowRect(hwnd)
    window_width = right - left
    window_height = bottom - top
    screenshot = 检测框模块.get_window_screenshot(hwnd)
    target_center = get_image_center(image_path, screenshot)
    if target_center is not None:
        movefb(hwnd, left, top, window_width, window_height, model, target_center, offset_x, offset_y, click_type)
        print("任务执行成功")
    else:
        print("未找到目标图片")